package com.neusoft.databus.core.converter;

import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.neusoft.bizcore.web.utils.JsonUtils;
import com.neusoft.databus.common.bean.CommandBean;
import com.neusoft.databus.common.bean.MetricBean;
import com.neusoft.databus.common.bean.ResourceBean;
import com.neusoft.databus.common.dto.GatewayDTO;
import com.neusoft.databus.common.dto.MetricDTO;
import com.neusoft.databus.common.dto.MetricGroupDTO;
import com.neusoft.databus.common.dto.ResourceDTO;
import com.neusoft.databus.core.service.MetricGroupService;

/**
 * 采集命令bean转换
 *
 * @author sunchf
 * @date 2019年1月7日 上午11:12:55
 */
@Component
public class CommandConverter {

    @Autowired
    private MetricGroupService metricGroupService;

    public CommandBean toCommand(final ResourceDTO dto) {
        final CommandBean commandBean = new CommandBean();

        final GatewayDTO gateway = dto.getGateway();
        commandBean.setConnType(gateway.getPhysicalConnType());
        commandBean.setConnectTimeout(gateway.getConnectTimeout());
        commandBean.setConnectRetry(gateway.getConnectRetry());
        commandBean.setConnectionStr(gateway.getConfig());
        commandBean.setGateway(gateway.getCode());
        // 命令中，有且只有一个指标组
        final MetricGroupDTO metricGroup = dto.getMetricGroups().get(0);
        commandBean.setProtocol(metricGroup.getProtocol());
        commandBean.setUsageType(metricGroup.getUsageType());
        commandBean.setProtocolConfig(metricGroup.getConfig());

        final ResourceBean resourceBean = new ResourceBean();
        resourceBean.setName(dto.getName());
        resourceBean.setCode(dto.getCode());

        if (!StringUtils.isEmpty(dto.getConfig())) {
            final Map<String, Object> extendAttibute = JsonUtils.jsonToMap(dto.getConfig());
            resourceBean.getConfig().putAll(extendAttibute);
        }

        final List<MetricDTO> metrics = metricGroup.getMetrics();
        metrics.stream().map(it -> {
            final MetricBean metric = new MetricBean();
            metric.setName(it.getName());
            metric.setCode(it.getCode());
            metric.setVariable(it.getVariable());
            metric.setCommand(it.getCommand());
            metric.setValueType(it.getValueType());
            metric.setRule(JsonUtils.jsonToMap(it.getRule()));
            metric.setUnit(it.getUnit());
            return metric;
        }).forEach(resourceBean.getMetrics()::add);
        commandBean.getResourceBean().add(resourceBean);

        return commandBean;
    }

    public CommandBean toCommand(final List<ResourceDTO> resources) {
        final CommandBean commandBean = new CommandBean();

        final Optional<ResourceDTO> minResource =
                resources.stream().min((o1, o2) -> {
                    return o1.getExecutionCycle() > o2.getExecutionCycle() ? 1 : -1;
                });

        final GatewayDTO gateway = minResource.get().getGateway();
        commandBean.setConnType(gateway.getPhysicalConnType());
        commandBean.setConnectTimeout(gateway.getConnectTimeout());
        commandBean.setConnectRetry(gateway.getConnectRetry());
        commandBean.setConnectionStr(gateway.getConfig());
        commandBean.setGateway(gateway.getCode());
        // 理论上，能够批处理的资源，指标组配置必须是相同的
        final MetricGroupDTO metricGroup = minResource.get().getCollectedMetricGroup();
        commandBean.setProtocol(metricGroup.getProtocol());
        commandBean.setUsageType(metricGroup.getUsageType());
        commandBean.setProtocolConfig(metricGroup.getConfig());

        resources.forEach(dto -> {
            final ResourceBean resourceBean = new ResourceBean();
            resourceBean.setName(dto.getName());
            resourceBean.setCode(dto.getCode());

            if (!StringUtils.isEmpty(dto.getConfig())) {
                final Map<String, Object> extendAttibute = JsonUtils.jsonToMap(dto.getConfig());
                resourceBean.getConfig().putAll(extendAttibute);
            }

            final List<MetricDTO> metrics =
                    this.metricGroupService.findByCode(dto.getCollectedMetricGroup().getCode()).getMetrics();
            metrics.stream().map(it -> {
                final MetricBean metric = new MetricBean();
                metric.setName(it.getName());
                metric.setCode(it.getCode());
                metric.setVariable(it.getVariable());
                metric.setCommand(it.getCommand());
                metric.setValueType(it.getValueType());
                metric.setRule(JsonUtils.jsonToMap(it.getRule()));
                metric.setUnit(it.getUnit());
                return metric;
            }).forEach(resourceBean.getMetrics()::add);

            commandBean.getResourceBean().add(resourceBean);
        });

        return commandBean;
    }
}
